﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data.SqlClient;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CreateNFetchTestService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        public string fetchTestXml(int testID, bool withAnswers)
        {
            return getTest(testID, withAnswers, true);
        }

        public string fetchTestHtml(int testID, bool withAnswers)
        {
            return getTest(testID, withAnswers, false);
        }

        public string getTest(int testID, bool withAnswers, bool isXml)
        {
            SqlConnection myConnection = new SqlConnection(getSqlConnectionString());
            myConnection.Open();

            string serializedAssessment = "";

            try
            {
                SqlDataReader myReader = null;
                SqlCommand myCommand = new SqlCommand("SELECT * FROM Assessments WHERE id = '" + testID + "'", myConnection);
                myReader = myCommand.ExecuteReader();
                while (myReader.Read())
                {
                    serializedAssessment = myReader["assessment"].ToString();
                }
                myReader.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Assessment assessment = null;

            byte[] assessmentStringBytes = Convert.FromBase64String(serializedAssessment);

            MemoryStream memoryStream = new MemoryStream(assessmentStringBytes);
            BinaryFormatter binaryFormatter = new BinaryFormatter();

            assessment = (Assessment)binaryFormatter.Deserialize(memoryStream);
            memoryStream.Close();

            myConnection.Close();

            string assessmentString;
            if (isXml)
            {
                if (withAnswers)
                    assessmentString = assessment.getAssessmentXmlWithAnswers();
                else
                    assessmentString = assessment.getAssessmentXml();
            }
            else
            {
                if(withAnswers)
                    assessmentString = assessment.getAssessmentHtmlWithAnswers();
                else
                    assessmentString = assessment.getAssessmentHtml();
            }
            return assessmentString;
        }


        public int createTest(string subject)
        {
            int assessmentDatabaseId = 0;
            SqlConnection myConnection = new SqlConnection(getSqlConnectionString());
            myConnection.Open();

            Assessment assessment = new Assessment();
            assessment.Id = 1;
            assessment.Name = subject + " Test " + assessment.Id;
            assessment.CreatedDate = DateTime.Now;

            try
            {
                SqlDataReader myReader2 = null;
                SqlCommand myCommand2 = new SqlCommand("SELECT [questionsTrueOrFalse].* FROM [questionsTrueOrFalse] " +
                                "LEFT JOIN [QuestionSubjects] " +
                                "ON [questionsTrueOrFalse].[Subject] = [QuestionSubjects].[id] " +
                                "WHERE [QuestionSubjects].[Name] = '" + subject + "'", myConnection);
                myReader2 = myCommand2.ExecuteReader();
                while (myReader2.Read())
                {
                    int questionId = Int16.Parse(myReader2["Id"].ToString());
                    string text = myReader2["Text"].ToString();
                    string correctAnswerString = myReader2["CorrectAnswer"].ToString();
                    bool correctAnswer = false;
                    if (correctAnswerString == "True")
                        correctAnswer = true;

                    assessment.addQuestion(new TrueFalseQuestion(questionId, text, correctAnswer));
                }
                myReader2.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            
            try
            {
                SqlDataReader myReader3 = null;
                SqlCommand myCommand3 = new SqlCommand("SELECT [questionsMultipleChoice].* FROM [questionsMultipleChoice] " +
                                "LEFT JOIN [QuestionSubjects] " +
                                "ON [questionsMultipleChoice].[Subject] = [QuestionSubjects].[id] " +
                                "WHERE [QuestionSubjects].[Name] = '" + subject + "'", myConnection);
                myReader3 = myCommand3.ExecuteReader();
                while (myReader3.Read())
                {
                    int questionId = Int16.Parse(myReader3["Id"].ToString());
                    string text = myReader3["Text"].ToString();
                    int correctAnswer = Int16.Parse(myReader3["CorrectAnswer"].ToString());
                    List<string> finalAnswers = new List<string>();
                    string combinedAnswers = myReader3["Answers"].ToString();
                    string[] splitAnswers = combinedAnswers.Split('|');
                    foreach (string answer in splitAnswers)
                    {
                        finalAnswers.Add(answer);
                    }

                    assessment.addQuestion(new MultipleChoiceQuestion(questionId, text, finalAnswers, correctAnswer));
                }
                myReader3.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            

            MemoryStream memoryStream = new MemoryStream();
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(memoryStream, assessment);

            string serializedAssessment = Convert.ToBase64String(memoryStream.ToArray());

            SqlDataReader myReader4 = null;
            SqlCommand myCommand4 = new SqlCommand("INSERT INTO Assessments (Subject, Title, Date, Assessment) VALUES ('" + subject + "', '" + assessment.Name + "', '" + assessment.CreatedDate + "', '" + serializedAssessment + "') SELECT @@IDENTITY AS AssessmentId", myConnection);
            myReader4 = myCommand4.ExecuteReader();
            while (myReader4.Read())
            {
                assessmentDatabaseId = Int16.Parse(myReader4["AssessmentId"].ToString());
                
            }
            myReader4.Close();
            myConnection.Close();

            return assessmentDatabaseId;
        }



        public int[] fetchTestNumbers(string subject)
        {
            SqlConnection myConnection = new SqlConnection(getSqlConnectionString());
            myConnection.Open();

            List<int> listOfTests = new List<int>();

            try
            {
                SqlDataReader myReader = null;
                SqlCommand myCommand = new SqlCommand("SELECT * FROM Assessments WHERE Subject = '" + subject + "'", myConnection);
                myReader = myCommand.ExecuteReader();
                while (myReader.Read())
                {
                    listOfTests.Add(Int16.Parse(myReader["id"].ToString()));
                }
                myReader.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            myConnection.Close();


            return listOfTests.ToArray();
        }

        private string getSqlConnectionString()
        {
            return @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\TestingServices.mdf;Integrated Security=True;User Instance=True";
        }
    }

}
